package com.llw.notify.setting;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Environment;
import android.util.Log;

import androidx.annotation.Nullable;

import com.llw.notify.util.ContextHelper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;

public class SettingsManager {
    private static final String TAG = SettingsManager.class.getSimpleName();
    private static final String filename = "local_cache";
    private static final String blackWordsKey = "blackWords";
    private static final String blackAppsKey = "blackApps";
    private static final String syncSwitchKey = "syncSwitch";
    private static final String senderEmailKey = "senderEmail";
    private static final String senderEmailPassportKey = "senderEmailPassport";
    private static final String receiverEmailKey = "receiverEmail";
    private static final String splitter = ",";

    // 导出导入时使用的标签
    private static final String blackWordsTag = "# black_words";
    private static final String blackAppsTag = "# black_apps";
    private static final String exportFilename = "black_values.txt";
    private static final File blackValuesFile = new File(
            Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOCUMENTS).getPath(),
            exportFilename);

    // 忽略哪些应用的通知
    private static final ArrayList<String> defaultBlackApps = new ArrayList<String>() {{
        add("com.netease.mail");                     // 网易邮箱
        add("com.netease.cloudmusic");               // 网易云音乐
        add("com.coloros.securitypermission");       // 系统权限
        add("com.coloros.shortcuts");                // breeno快捷指令
        add("com.android.systemui");                 // 系统界面：连接usb之类产生的通知
        add("com.kugou.android.lite");               // 酷狗概念版
        add("com.coloros.gallery3d");                // 手机相册
        add("com.taobao.taobao");                    // 淘宝
        add("com.coloros.weather.service");          // 天气
        add("com.coloros.alarmclock");               // 时钟
        add("com.coloros.oppoguardelf");             // 电池
    }};
    private static final String defaultBlackAppsString = stringArrayToString(defaultBlackApps);

    // 忽略包含哪些关键字的通知
    private static final ArrayList<String> defaultBlackWords = new ArrayList<String>() {{
        add("淘友圈");
        add("云闪付-签到");
    }};
    private static final String defaultBlackWordsString = stringArrayToString(defaultBlackWords);

    private static String stringArrayToString(final ArrayList<String> array) {
        StringBuilder result = new StringBuilder();
        for (String blackWord : array) {
            result.append(blackWord).append(splitter);
        }
        return result.toString();
    }

    private static String getStringBase(final String key, final String defaultValue) {
        return ContextHelper.application().getSharedPreferences(filename, Context.MODE_PRIVATE).getString(key, defaultValue);
    }

    public static void initSettings() {
        SharedPreferences sharedPreferences = ContextHelper.application().getSharedPreferences(filename, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        String blackWords = sharedPreferences.getString(blackWordsKey, "");
        if (blackWords.isEmpty()) {
            editor.putString(blackWordsKey, defaultBlackWordsString);
            editor.apply();
        }

        String blackApps = sharedPreferences.getString(blackAppsKey, "");
        if (blackApps.isEmpty()) {
            editor.putString(blackAppsKey, defaultBlackAppsString);
            editor.apply();
        }
    }

    public static void exportToFile() {
        try {
            final FileOutputStream outputStream = new FileOutputStream(blackValuesFile);
            outputStream.write((blackWordsTag + "\n").getBytes());
            for (String blackWord : getBlackWords()) {
                outputStream.write((blackWord + "\n").getBytes());
            }
            outputStream.write((blackAppsTag + "\n").getBytes());
            for (String blackApp : getBlackApps()) {
                outputStream.write((blackApp + "\n").getBytes());
            }
            outputStream.close();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String importFromFile(final ImportMode mode) {
        if (!blackValuesFile.exists()) {
            Log.e(TAG, "找不到文件" + blackValuesFile.getPath());
            return "找不到文件：" + blackValuesFile.getPath();
        }
        try {
            FileInputStream inputStream = new FileInputStream(blackValuesFile);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            ArrayList<String> blackApps = new ArrayList<>();
            ArrayList<String> blackWords = new ArrayList<>();
            String line = null;

            // 读取屏蔽词
            line = reader.readLine();
            if (line == null || !line.trim().equals(blackWordsTag)) {
                Log.e(TAG, "不支持的文件格式");
                return "不支持的文件格式";
            }
            while ((line = reader.readLine()) != null && !line.trim().equals(blackAppsTag)) {
                blackWords.add(line.trim());
            }
            // 读取屏蔽应用
            while ((line = reader.readLine()) != null) {
                blackApps.add(line.trim());
            }

            reader.close();
            inputStream.close();

            // 写入 SharedPreferences
            switch (mode) {
                // 合并原有的屏蔽值
                case Merge:
                    blackWords.addAll(Arrays.asList(getBlackWords()));
                    blackApps.addAll(Arrays.asList(getBlackApps()));
                    updateBlackWords(stringArrayToString(new ArrayList<>(new HashSet<>(blackWords))));
                    updateBlackApps(stringArrayToString(new ArrayList<>(new HashSet<>(blackApps))));
                    break;
                // 直接覆盖原有的屏蔽值
                case Override:
                    updateBlackWords(stringArrayToString(blackWords));
                    updateBlackApps(stringArrayToString(blackApps));
                    break;
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return "导入成功";
    }

    private static void updateBlackValue(final String key, final String newValue) {
        SharedPreferences.Editor editor = ContextHelper.application()
                .getSharedPreferences(filename, Context.MODE_PRIVATE)
                .edit();
        editor.putString(key, newValue.replaceAll("\n", splitter));
        editor.apply();
    }

    public static void updateBlackWords(final String newValue) {
        updateBlackValue(blackWordsKey, newValue);
    }

    public static void updateBlackApps(final String newValue) {
        updateBlackValue(blackAppsKey, newValue);
    }

    public static void switchSync() {
        boolean sync = isSyncSwitchOn();
        SharedPreferences.Editor editor = ContextHelper.application()
                .getSharedPreferences(filename, Context.MODE_PRIVATE)
                .edit();
        editor.putBoolean(syncSwitchKey, !sync);
        editor.apply();
        Log.i(TAG, !sync ? "转发开关被打开" : "转发开关被关闭");
    }

    public static void startSync() {
        SharedPreferences.Editor editor = ContextHelper.application()
                .getSharedPreferences(filename, Context.MODE_PRIVATE)
                .edit();
        editor.putBoolean(syncSwitchKey, true);
        editor.apply();
        Log.i(TAG, "转发开关被打开");
    }

    public static boolean isSyncSwitchOn() {
        SharedPreferences sp = ContextHelper.application().getSharedPreferences(filename, Context.MODE_PRIVATE);
        return sp.getBoolean(syncSwitchKey, true);
    }

    /**
     * 检查 content 是否包含设置中的屏蔽词
     *
     * @param content 要检查的字符串内容
     * @return 若包含屏蔽词则返回第一个查找到的屏蔽词，否则返回 null
     */
    @Nullable
    public static String hasBlackWords(final String content) {
        String[] blackWords = getStringBase(blackWordsKey, defaultBlackWordsString).split(splitter);
        for (String blackWord : blackWords) {
            if (content.contains(blackWord)) {
                return blackWord;
            }
        }
        return null;
    }

    public static boolean isInBlackApps(final String content) {
        return getStringBase(blackAppsKey, defaultBlackAppsString).contains(content);
    }

    public static String[] getBlackWords() {
        return getStringBase(blackWordsKey, defaultBlackWordsString).split(splitter);
    }

    public static String[] getBlackApps() {
        return getStringBase(blackAppsKey, defaultBlackAppsString).split(splitter);
    }

    /**
     * 设置发送方的邮箱地址以及授权码
     *
     * @param emailAddress 邮箱地址
     * @param emailPassport 邮箱授权码
     */
    public static void setSender(final String emailAddress, final String emailPassport) {
        SharedPreferences.Editor editor = ContextHelper.application().getSharedPreferences(filename, Context.MODE_PRIVATE).edit();
        editor.putString(senderEmailKey, emailAddress);
        editor.putString(senderEmailPassportKey, emailPassport);
        editor.apply();
    }

    /**
     * 设置接收方的邮件地址
     */
    public static void setReceiver(final String emailAddress) {
        SharedPreferences.Editor editor = ContextHelper.application().getSharedPreferences(filename, Context.MODE_PRIVATE).edit();
        editor.putString(receiverEmailKey, emailAddress);
        editor.apply();
    }

    public static String getSenderEmail() {
        return getStringBase(senderEmailKey, "");
    }

    public static String getSenderEmailPassport() {
        return getStringBase(senderEmailPassportKey, "");
    }

    public static String getReceiverEmail() {
        return getStringBase(receiverEmailKey, "");
    }

    public static boolean isEmailInfoSetup() {
        String value = getSenderEmail();
        if (value.isEmpty()) {
            return false;
        }
        value = getSenderEmailPassport();
        if (value.isEmpty()) {
            return false;
        }
        value = getReceiverEmail();
        return !value.isEmpty();
    }
}
